package meminin.naivebayes;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import meminin.model.Label;
import meminin.model.MySqlTrainingData;

/**
 *
 * @author Danang
 */
public class NaiveBayesTrainingData extends MySqlTrainingData {
    
    protected String dataPath;
    protected ArrayList<Label> labels;
    
    public NaiveBayesTrainingData(String filePath, String hostName, String dbName, String tableName, String dbUser, String dbPassword) {
        super(hostName, dbName, tableName, dbUser, dbPassword);
        dataPath = filePath;
        labels = new ArrayList<Label>();
    }
    
    public String getDbName() {
        return dbName;
    }
    
    public String getTableName() {
        return tableName;
    }

    /**
     * @return the dataPath
     */
    public String getDataPath() {
        return dataPath;
    }

    /**
     * @param dataPath the dataPath to set
     */
    public void setDataPath(String dataPath) {
        this.dataPath = dataPath;
    }

    /**
     * @return the labels
     */
    public ArrayList<Label> getLabels() {
        return labels;
    }

    /**
     * @param labels the labels to set
     */
    public void setLabels(ArrayList<Label> labels) {
        this.labels = labels;
    }
    
    private void doRead() {
        try {
            FileInputStream fs = new FileInputStream(dataPath);
            DataInputStream in = new DataInputStream(fs);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String str;
            while ((str = br.readLine()) != null) {
                if (str.length() > 1) {
                    parseData(str);
                }
            }
            in.close();
        } catch (Exception ex) {
            Logger.getLogger(NaiveBayesTrainingData.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void parseData(String str) {
        String t = str.toUpperCase();
        if (t.startsWith("%")) {
        } else if (t.startsWith("@RELATION")) {
            String[] split = str.split("\\s+");
            connector.createTable(split[1]);
            tableName = split[1];
        } else if (t.startsWith("@ATTRIBUTE")) {
            String[] split = str.split("\\s+");
            String col = split[split.length - 2];
            String type = split[split.length - 1];
            NaiveBayesLabel tempLabel = new NaiveBayesLabel(col);
            ArrayList<String> labelValues = new ArrayList<String>();
            if (type.startsWith("{") && type.endsWith("}")) { // check if type = enum
                String tmp = type.substring(1, type.length() - 1);
                String[] enumString = tmp.split(",");
                type = "('";
                for (int i = 0; i < enumString.length; i++) {
                    type = type.concat(enumString[i]).concat("','");
                    labelValues.add(enumString[i]);
                }
                type = type.substring(0, type.length() - 2).concat(")");
                connector.addColumn(col, "ENUM", type);
            } else if (type.compareToIgnoreCase("numeric") == 0) {
                // numeric attribute : float
                connector.addColumn(col, "FLOAT", "(20)");
            } else if (type.compareToIgnoreCase("string") == 0) {
                // string attribute  
                connector.addColumn(col, "VARCHAR", "(20)");
            } else if (type.compareToIgnoreCase("date") == 0) {
                // date attribute  
                // not implemented yet
            }
            tempLabel.setValues(labelValues);
            labels.add(tempLabel);
        } else if (t.startsWith("@DATA")) {
            // set class atribute
            NaiveBayesLabel tempLabel = (NaiveBayesLabel) labels.get(labels.size()-1);
            tempLabel.setIsClassAtribute(true);
            System.out.println("label "+tempLabel.getDesc());
            NaiveBayesLabel tempLabel2 = (NaiveBayesLabel) labels.get(labels.size()-1);
            System.out.println("isClass "+tempLabel2.isIsClassAtribute());
            connector.prepareInsert();
        } else {
            String[] split = str.split(",");
            connector.insertRow(split);
        }
    }

    private void getData() {
        try {
            ResultSet rs = connector.getTableData();
            int count=0;
            while (rs.next()) {
                int colType = rs.getType();
                count++;
                System.out.println("Column 1 is type " + colType);
            }
            System.out.println("jumlah "+count);
        } catch (SQLException ex) {
            Logger.getLogger(NaiveBayesTrainingData.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void readTrainingData() {
        doRead();
        getData();
    }
    
    public Label getClassLabel() {
        Label nbl = null;
        for (Label s : labels) {
            if (((NaiveBayesLabel)s).isIsClassAtribute())
                nbl = s;
        }
        return nbl;
    }
    
    public int getCountFromQuery(String query) {
        try {
            ResultSet rs = connector.executeRead(query);
            rs.last();
            return rs.getRow();
        } catch (SQLException ex) {
            Logger.getLogger(NaiveBayesTrainingData.class.getName()).log(Level.SEVERE, null, ex);
        }
        return -1;
    }
    
}
